#include "pch.hpp"
#include "MainWindow.hpp"

// Gui
#include <WinUi/Application.hpp>
#include <WinUi/WidgetImpl.hpp>




MainWindow::MainWindow(services::provider::ptr provider)
	: m_engine(createEngine(provider))
	, m_uiSystem(m_engine->uiSystem())
{
	auto scriptSystem = m_engine->scriptSystem();

	Game::declareType(scriptSystem);
	GameState::declareType(scriptSystem);

	Game::registerType(scriptSystem);
	GameState::registerType(scriptSystem);

	WinUi::Application::instance().idle.connect(boost::bind(&MainWindow::onIdle, this));

	m_game = Game::create(m_engine, provider);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

MainWindow::~MainWindow()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




void MainWindow::onIdle()
{
	m_game->update();
}
///////////////////////////////////////////////////////////////////////////////////////////////////




LRESULT MainWindow::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_PAINT:
		{
			// core::Window already implements WM_PAINT and paints
			// the window' client area in white, however we don't need
			// that, as DirectX already copies the backbuffer into the dc.
			onIdle();
			return 0;
		}
	case WM_ENTERSIZEMOVE:
		{
			return 0;
		}
	case WM_EXITSIZEMOVE:
		{
			// Only actually resize the engine, when we're in windowed mode, and
			// when the window is not minimized
			if(m_engine->videoDevice()->displayMode().windowMode == WindowMode::Windowed && !minimized())
			{
				int2 size = clientSize();
				m_engine->resize(size.x, size.y);
			}

			return __super::msgProc(msg, wParam, lParam);
		}
	case WM_CHAR:
		{
			// Unfortunately, We need to call it manually
			m_uiSystem->processInput(wParam);
			return 0;
		}
	default:
		{
			// We don't care about the rest
			return WinUi::MainWindow::msgProc(msg, wParam, lParam);
		}
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




Engine::IEngine::ptr MainWindow::createEngine(services::provider::ptr provider)
{
	DisplayMode mode(size().x, size().y, WindowMode::Windowed, std::make_pair(1, 60));
	EngineInfo info(mode);
	info.window          = d->wnd;
	info.serviceProvider = provider;

	return Engine::IEngine::create(info);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
